#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @author: Florian Dorn <florian.dorn@gmail.com>
# @package: agenda
# @license: GNU GPLv2
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

import gobject
import gconf
import gnomekeyring

class Password(object):
	pw = ""
	def __init__(self,pw=""):
		self.pw = pw
		
	def __str__(self):
		return self.pw
"""
This is wrapper around configuration files.
It will use gconf if possible, next ConfigObj is tried.

Maybe have a look at ConfigParser:
http://stackoverflow.com/questions/118096/how-can-i-parse-a-comma-delimited-string-into-a-list-caveat
"""
class Config(gobject.GObject):
	boolean = ["hide_finished"]
	integers = ["width","height","refresh","reminder","num_days"]
	strings = ["default_color","accelerator"]
	lists = ["active_providers"]
	passwords = []
	values = {	"width": 350, "height":500,"refresh":30,
					"reminder":45,"default_color":"AABBCC",
					"active_providers": [],"num_days": 30, "accelerator":'<Alt>F12'}

	def __init__(self):
		self.toplevel  = "/apps/agenda-gtk"
		self.client = gconf.client_get_default()
		self.__first_time_usage = False
		self.__first_time_usage = not self.client.dir_exists(self.toplevel)
		self.client.notify_add(self.toplevel, self.config_change_event)
		self._keyring = gnomekeyring.get_default_keyring_sync()
		if self.__first_time_usage:
			for path,default in self.values.items(): 
				self.set(path, default)
		#self._keyring.set_application_name("Agenda")
		
	def config_change_event(self, gconf_client, *args, **kwargs):
		#self.get_config()
		print args
		print kwargs
	def get_bool(self,path):
		v = self.client.get_bool(self.__get_path(path))
		if(v == None):
			self.set_bool(path,self.values[path])
		else:
			self.values[path] = v
		return self.values[path]
	def get_int(self,path):
		v = self.client.get_int(self.__get_path(path))
		if(v == None):
			self.set_int(path,self.values[path])
		else:
			self.values[path] = v
		return self.values[path]
	def get_float(self,path):
		v = self.client.get_float(self.__get_path(path))
		if(v == None):
			self.set_float(path,self.values[path])
		else:
			self.values[path] = v
		return self.values[path]
	def get_string(self,path):
		v = self.client.get_string(self.__get_path(path))
		if(v == None):
			self.set_string(path,self.values[path])
		else:
			self.values[path] = v
		return self.values[path]
	def get_list(self,path):
		v = self.client.get_list(self.__get_path(path),'string')
		if(v == None):
			self.set_list(path,self.values[path])
		else:
			self.values[path] = v
		return self.values[path]
	def get_password(self,path):
		if(path in self.passwords):
			path_entries = path.split("/")
			name = "/".join(path_entries[1:])
			attrs = {
				"service": path_entries[-2],
				"name": name
			}
			try:
				items = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, attrs)
				self.values[path] = Password(items[0].secret)
			except:
				return ""
			
		return self.values[path]
	def set_int(self,path,value):
		self.client.set_int(self.__get_path(path),int(value))
	def set_string(self,path,value):
		self.client.set_string(self.__get_path(path),str(value))
	def set_list(self,path,value):
		value = map(str,value)
		self.client.set_list(self.__get_path(path),"string",list(value))
	def set_bool(self,path,value):
		self.client.set_bool(self.__get_path(path),bool(value))

	def set(self,path,value):
		if(path in Config.integers):
			self.set_int(path,value)
		elif(path in Config.strings):
			self.set_string(path,value)
		elif(path in Config.lists):
			self.set_list(path,value)
		elif(path in Config.boolean):
			self.set_bool(path,value)
		elif (path in Config.passwords):
			self.set_password(path, value)
		else:
			#print "Skipping '%s'. It has no associated type." % path
			pass
	def get(self,path):
		if(path in Config.integers):
			return self.get_int(path)
		elif(path in Config.strings):
			return self.get_string(path)
		elif(path in Config.lists):
			return self.get_list(path)
		elif(path in Config.boolean):
			return self.get_bool(path)
		elif (path in Config.passwords):
			return self.get_password(path,)
		else:
			return None
	def __get_path(self,path):
		return "/".join((self.toplevel,path))
	
	def __register_values(self,values,prefix = ""):
		"""
		register new values
		values is a map of key, default paris
		the type is determined by type(default)
		"""
		for path, default in values.items():
			#print (path,default)
			path = "/".join((prefix,path))
			
			
			self.__register_value(path, default)
	def __register_value(self,path,default):
		self.values[path] = default
		t = type(default)
		#print "registering '%s' with type %s" % (path,t)
		if(t == int):
			self.integers.append(path)
		elif (t == str):
			self.strings.append(path)
		elif (t == list):
			self.lists.append(path)
		elif (t == bool):
			self.boolean.append(path)
		elif (t == Password):
			self.passwords.append(path)
	def register_plugin(self,plugin):
		pluginname = plugin.__module__
		prefix = "/".join( ("plugins",pluginname) )
		self.__register_values(plugin.config_defaults,prefix)
		
	def set_password(self,path,value):
		self.set_string(path, "")
		path_entries = path.split("/")
		name = "/".join(path_entries[1:])
		attrs = {
			"service": path_entries[-2],
			"name": name
		}
		
		s = gnomekeyring.item_create_sync(	gnomekeyring.get_default_keyring_sync(),
										gnomekeyring.ITEM_GENERIC_SECRET, "agenda-gtk/%s" % name, attrs, value, True)
	def sync(self):
		"""
		request the settings to be written to disk
		"""
		#self.client.
		pass
	
	def get_plugin_settings(self,plugin):
		pluginname = plugin.__module__
		prefix = "/".join( ("plugins",pluginname))
		
		settings = {}
		for cv in plugin.config_defaults.keys():
			settings[ cv ] = self.get("/".join( (prefix,cv) ))
		#print settings
		
		return settings
	
	def migrate_settings(self,settings,path=""):
		"""
		migrate settings from ConfigObj
		"""
		self.__first_time_usage = False
		t = settings
		for key, value in t.items():

			if(path != ""):
				newpath = "/".join((path,key))
			else:
				newpath = key
			if type(value) in (str,list):
				#print "%s (%s): %s" %(newpath,type(value),value)
				self.set(newpath,value)
			else:
				self.migrate_settings(value,newpath)
		self.sync()
		
	def first_time_usage(self):
		return self.__first_time_usage
